package com.anjie.powerproject.schedule;

import com.anjie.powerproject.entity.DataDay;
import com.anjie.powerproject.entity.GraphInfo;
import com.anjie.powerproject.entity.StationInfo;
import com.anjie.powerproject.repository.DataDayRepository;
import com.anjie.powerproject.service.GraphInfoService;
import com.anjie.powerproject.service.StationInfoService;
import com.anjie.powerproject.strategy.pojo.DayWeather;
import com.anjie.powerproject.strategy.service.WeatherForecastService;
import com.anjie.powerproject.strategy.utils.DateUtils;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * 用于按照规则定时修改图谱使用时间的定时任务   图谱更新
 */
@RestController
@RequestMapping(value = "schedule/update")
@Component
public class UpdateGraphTime {
    @Autowired
    GraphInfoService graphInfoService;

    @Autowired
    WeatherForecastService weatherForecastService;

    @Autowired
    StationInfoService stationInfoService;

    @Autowired
    DataDayRepository dataDayRepository;

    @PersistenceContext
    private EntityManager entityManager;

     @RequestMapping(value = "execute")
    // 每天 22:35 时更新表中按规则匹配的图谱使用时间
//    @Scheduled(cron = "0 31 16 * * ?")
    public void update() throws ParseException {
        // 首先获取所有使用规则判断的图谱的规则
        List<GraphInfo> graphs = graphInfoService.findGraphInfoByUseRule(1);
        StationInfo stationInfo = stationInfoService.findStationInfoLimitFirst();
        if (stationInfo == null) {
            throw new RuntimeException("站点信息为空");
        }
        /**************2.5*******************/
//         Date date=new Date();
//         Double TodayTemperature=dataDayRepository.getDataDayValue(stationInfo.getTemperatureCode(), new SimpleDateFormat("yyyy-MM-dd").format(date));
         // 获取前五天加后十天的天气数据，总共16天（按天算）
//         Calendar calendar = new GregorianCalendar();
//         calendar.add(Calendar.DATE, -5);
//         String startTime=calendar.get(Calendar.YEAR)+"-"+calendar.get(Calendar.MONTH)+"-"+calendar.get(Calendar.DATE);
//         calendar.add(Calendar.DATE, 15);
//         String endTime=calendar.get(Calendar.YEAR)+"-"+calendar.get(Calendar.MONTH)+"-"+calendar.get(Calendar.DATE);
//         List<DataDay> dataDays=dataDayRepository.getDataDayList(stationInfo.getTemperatureCode(),startTime,endTime);

         //            // 获取室内温度开始规则
//            Integer startDayNumOutdoor = graphInfo.getStartDayNumIndoor();
//            Integer startLevelOutdoor  = graphInfo.getStartLevelIndoor();
//            Integer startRelsOutdoor  = graphInfo.getStartRelsIndoor();
//            Integer startTemOutdoor  = graphInfo.getStartTemIndoor();

        /**************2.5*******************/
        String areaCode = stationInfo.getCityCode();
         // 然后获取前五天加后十天的天气数据,总共16天（按天算）
         // 注意这里的地区码应该另外获取
         List<DayWeather> weathers = null;
         weathers = weatherForecastService.getForecastDayWeatherByAddrCode(areaCode);

         // 遍历graphs，匹配符合条件的天气数据以调整图谱的使用时间
        for (GraphInfo graphInfo: graphs) {
            // 获取十六天的最高温度
            Double[] highTems = weathers.stream().map(DayWeather::getTemphigh).toArray(Double[]::new);
            // 获取十六天的最低温度
            Double[] lowTems = weathers.stream().map(DayWeather::getTemplow).toArray(Double[]::new);

            // 获取室外温度开始规则
            Integer startDayNum = graphInfo.getStartDayNum();
            Integer startLevel = graphInfo.getStartLevel();
            Integer startRels = graphInfo.getStartRels();
            Integer startTem = graphInfo.getStartTem();


            // 首先匹配开始规则:
            // startLevel == 1:最高温, startLevel == 2:最低温
            Double[] tems = lowTems;
            if (startLevel == 1) {
                tems = highTems;
            }
            // startRels == 1: 大于，startRels == 2: 小于
            int idx = 0;
            int count = 0;
            while (idx < tems.length) {
                if (startRels == 1) {
                    if (tems[idx] >= startTem) {
                        count += 1;
                        if (count == startDayNum) {
                            break;
                        }
                    } else {
                        count = 0;
                    }
                } else {
                    if (tems[idx] <= startTem) {
                        count += 1;
                        if (count == startDayNum) {
                            break;
                        }
                    } else {
                        count = 0;
                    }
                }
                idx += 1;
            }
            int startRes = -1;

            // 如果找到了匹配的日期
            if (count == startDayNum) {
                startRes = idx;
            }

            // 获取结束规则
            Integer endDayNum = graphInfo.getEndDayNum();
            Integer endLevel = graphInfo.getEndLevel();
            Integer endRels = graphInfo.getEndRels();
            Integer endTem = graphInfo.getEndTem();
            // 然后匹配结束规则
            if (endLevel == 1) {
                tems = highTems;
            } else {
                tems = lowTems;
            }
            idx = tems.length - 1;
            count = 0;
            while (idx > 0) {
                if (endRels == 1) {
                    if (tems[idx] >= endTem) {
                        count += 1;
                        if (count == endDayNum) {
                            break;
                        }
                    } else {
                        count = 0;
                    }
                } else {
                    if (tems[idx] <= endTem) {
                        count += 1;
                        if (count == endDayNum) {
                            break;
                        }
                    } else {
                        count = 0;
                    }
                }
                idx -= 1;
            }

            int endRes = -1;
            // 如果找到了匹配的日期
            if (count == endDayNum) {
                endRes = idx + count - 1;
            }

            // 检查结束规则匹配的日期是否在开始规则匹配的日期之后
            // 若是，则更新图谱使用天数
            if (endRes != -1 && startRes != -1 && startRes < endRes) {
                // 擦除在session中缓存的对象
                Session session = entityManager.unwrap(org.hibernate.Session.class);
                graphInfo.setGraphStartTime(DateUtils.mdFormat.format(weathers.get(startRes).getSdate()));
                graphInfo.setGraphEndTime(DateUtils.mdFormat.format(weathers.get(endRes).getSdate()));
                session.evict(graphInfo);

                graphInfoService.updateGraphInfo(graphInfo);
            }
        }

    }
}